#include "BackgroundImageGenerator/mean.h"
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include "ConfFileReader.h"

BackgroundImageGeneratorMean::BackgroundImageGeneratorMean(int capacity)
:alpha(1.0f/capacity),isInit(false){

}

BackgroundImageGeneratorMean::~BackgroundImageGeneratorMean(){

}

BackgroundImageGeneratorMean::BackgroundImageGeneratorMean(const BackgroundImageGeneratorMean& other){
	*this=other;
}

const BackgroundImageGeneratorMean& BackgroundImageGeneratorMean::operator=(const BackgroundImageGeneratorMean& other){
	alpha=other.alpha;

	average=other.average.clone();

	isInit=true;
	return *this;
}

void BackgroundImageGeneratorMean::generate(const cv::Mat& src, cv::Mat& dst){
	if(!isInit) initialize(src);

	average.convertTo(dst,src.type());
}

void BackgroundImageGeneratorMean::update(const cv::Mat& src){
	if(!isInit) initialize(src);
	if(previousUpdate.data==src.data) return;

	cv::accumulateWeighted(src,average,alpha);
	previousUpdate=src;
}

void BackgroundImageGeneratorMean::train(const std::vector<cv::Mat>& src){
	for(std::vector<cv::Mat>::const_iterator it=src.begin();it!=src.end();it++){
		update(*it);
	}
}

void BackgroundImageGeneratorMean::save(const std::string& path)const{
	if(!isInit) throw "This Background Image Generator has not initialized yet.";

	std::string conffile=path+"average.conf";
	std::string averageImg=path+"average.xml";

	std::ofstream ofs(conffile.c_str());
	ofs << "alpha:" << alpha << std::endl;

	cv::FileStorage fs(averageImg,cv::FileStorage::WRITE);
	cv::WriteStructContext ws(fs, "mat_array", CV_NODE_SEQ);
	cv::write(fs,"",average);

}

void BackgroundImageGeneratorMean::load(const std::string& path){
	std::string conffile=path+"average.conf";
	std::string averageImg=path+"average.xml";

	mmpl::ConfFileReader cfr(conffile);
	alpha=static_cast<float>(atof(cfr["alpha"].c_str()));

	cv::FileStorage fs(averageImg,cv::FileStorage::READ);
	cv::FileNode node(fs.fs,NULL);
	cv::read(node["mat_array"][0],average);

	isInit=true;

}

void BackgroundImageGeneratorMean::initialize(const cv::Mat& img){
	average.create(img.rows,img.cols,CV_32FC3);
	IplImage temp=average;
	img.convertTo(average,CV_32FC3);
	isInit=true;
}
